
function TreeNode() {
	this.expanded = true;
	this.selected = false;
	this.data = null;
	this.path = [];
	this.children = null;
	this.leaf = false;
	this.type = '';
	this.parent = null;
	
	this.treeProvider = null;
	
	this.getType = function()  {
		var res = '';
		if (this.leaf == true) {
			res += 'leaf ';
		}
		if (this.leaf != true) {
			res += 'notleaf ';
		}
		
		
		if (this.parent == null) {
			res += 'root ';
		}
		
		if (this.leaf != true) {
			if (this.children != null && this.children.length > 0) {
				res += 'haschildren ';
			}
			if (this.children != null && this.children.length == 0) {
				res += 'empty ';
			}
			
			if (this.expanded == true) {
				res += 'expanded ';
			} else {
				res += 'collapsed ';
			}
		}
		
		if (this.selected == true) {
			res += 'selected ';
		} else {
			res += 'notselected ';
		}
		
		return res;
	},
	
	this.getChildren = function() {
			
			if (this.children != null) {
				return this.children;
			}
			this.children = [];
			
			var childrenFromData = this.treeProvider.getChildren(this.data);
			if (childrenFromData == null) {
				this.leaf = true;
				return;
			}
			this.leaf = false;
			
			for (var i = 0; i < childrenFromData.length; i++) {
				var newNode = new TreeNode();
				newNode.parent = this;
				newNode.data = childrenFromData[i];
				
				
				newNode.treeProvider = this.treeProvider;
				
				// most of the node functionality is options
				if (this.treeProvider.canHaveChildren != null) {
					newNode.leaf = !this.treeProvider.canHaveChildren(newNode.data);
				}
				
				
				newNode.path.concat(this.path);
				newNode.path.push(i);
				this.children.push(newNode);
			}
			
			return this.children;
	},
	
	this.setData = function(data) {
		this.data = data;
		this.children = null;
	}
}

function TreeDataProvider() {
	this.data = {},
	this.nodes = null;
	
	this.rootNode = new TreeNode(),
	
	this.setData = function(data) {
		this.rootNode.treeProvider = this.treeProvider;
		this.rootNode.data = data;
		this.rootNode.children = null;
		this.rootNode.expanded = true;
	},
	
	this.toggleNodeExpand = function(node) {
		this.nodes = null;
		if (node.leaf == true) {
			return;
		}
		node.expanded = !node.expanded;
	},
	
	this.expandNode = function(levels) {
	},
	
	this.getNodes = function() {
		if (this.nodes != null) {
			return this.nodes;
		}
		//alert('here');
		var res = [];
		this.getNodesRecursion(this.rootNode, res);
		this.nodes = res;
		return this.nodes;
	},
	
	this.getNodesRecursion = function(node, res) {
		res.push(node);
		
		if (!node.expanded) {
			return;
		}
		
		//alert(node.data.title+' '+node.data.id);
		var children = node.getChildren();
		for (var i = 0; children != null && i < children.length; i++) {
			var curNode = children[i];
			this.getNodesRecursion(curNode, res);
		}
	}
} 
